<?php

function apply_patch($patch)
{
	$config_php = $patch->site_dir.'etc/conf.d/db.php';
	include ($config_php);
	require_once 'UpMysql.php';
	$db = new UpMysql($config);
	if (!$db->init()) {
		$patch->error = $db->error;
		return false;
	}
	$patch->db = $db;
	$status = true
		&& update_db_schema($patch)
	//	&& update_class_person($patch)
		&& update_move_author_url_to_class_item_author($patch)
		&& update_db_review_fields($patch)
		;
	return $status;
}

// 1.2.1
/**
 * update_db_schema обновление схемы DB.
 *
 * @param mixed $patch
 * @access public
 * @return boolean
 */
function update_db_schema ($patch)
{
	require_once 'MysqlImport.php';
	$patch_sql = $patch->patch_dir . 'patch.sql';
	$sql = file_get_contents($patch_sql);

	$prefix = $patch->db->db_prefix;
	$sql = str_replace('{{prefix}}', $prefix, $sql);

	$m = new MysqlImport(array('import_text' => $sql, 'db' => $patch->db));
	$status = $m->process();
	if (!$status) {
		$patch->error = $m->error;
	}
	return $status;
} // end of function update_db_schema

/**
 * update_class_person заполняем новую таблицу class_person
 *
 * @param mixed $patch
 * @access public
 * @return boolean
 */
/**
function update_class_person($patch)
{
	$db = $patch->db;
	$prefix = $db->db_prefix;

	// из класса member найдем членов всех сообществ
	$sql = "
		SELECT O.*, M.community_oid
	  FROM {$prefix}objects O INNER JOIN {$prefix}class_member M ON (O.oid = M.user_oid)
	";

	$result = $db->query($sql);

	while ($row = $db->getOne($result)) {
		$community_oid = $row['community_oid'];
		$user_data = unserialize($row['data']);

		$person = array(
			'community_oid' => $community_oid,
			     'fullname' => $user_data['fullname'],
		);

		// посмотрим, есть-ли похожая персона в DB
		$fullname_sql = $db->escape($person['fullname']);
		$sql = "
			SELECT *
			FROM {$prefix}class_person
			WHERE community_oid = {$community_oid} AND (fullname = '{$fullname_sql}')
			LIMIT 1
		";

		if (!$db->getOne($db->query($sql))) { // если похожей персоны нет, создадим
			// сохраним объект для структуры $member
			$date = time();
			$fperson = array(
							'type' => 'fperson',
							'data' => serialize($person),
						 'ctime' => date('Y-m-d H:i:s', $date),
						 'mtime' => date('Y-m-d H:i:s', $date),
				'is_deleted' => 0,
			);
			if (!$db->insert("{$prefix}objects", $fperson)) {
				$patch->error = $db->error;
				return false;
			}
			$person['oid'] = $db->insertId();

			// классифицируем
			$cperson = array(
				          'oid' => $person['oid'],
				'community_oid' => $person['community_oid'],
				         'name' => 'fullname',
				        'value' => $person['fullname'],
			);
			if (!$db->insert("{$prefix}class_person", $cperson)) {
				$patch->error = $db->error;
				return false;
			}
			// классифицируем
			$cperson = array(
				          'oid' => $person['oid'],
				'community_oid' => $person['community_oid'],
				         'name' => 'wikiname',
				        'value' => $person['wikiname'],
			);
			if (!$db->insert("{$prefix}class_person", $cperson)) {
				$patch->error = $db->error;
				return false;
			}
		}
	}
	return true;
}
 */

/**
 * string2wikiname c&p from Model/PersonManager
 */
/**
function string2wikiname ($str, $patch)
{
	require_once $patch->site_dir.'lib/translit/php/translit.php';
	$t = new Translit();
	$out = $t->Wikify($str);
	return $out;
} // end of method title2wikiname
 */

/**
 * update_move_author_url_to_class_item_author заполняем новую таблицу
 * class_item_author
 *
 * @param mixed $patch
 * @access public
 * @return boolean
 */
function update_move_author_url_to_class_item_author($patch)
{
	// обновить связи документ->автор. т.к. поле author_url теперь не
	// используется, а авторы хранятся в store_item_author
	//
	// иногда в author_url хранилось oid platonicauser_oid, очевидно теперь он
	// должен попасть в store_item_author.author_oid
	// для всех типов документов
	$db = $patch->db;
	$prefix = $db->db_prefix;

	// нам нужно обновить все объекты документов.
	// там где есть атрибут author_url, нуджно сформировать структуру authors (@see Model_Person)
	// author_url может содержать: NULL, oid объекта fpid_user или настоящий url
	// если автор идентифицирован через oid объекта, сделаем запись в class_item_author
	// так же может присутствовать url, тогда сохраним его в структуру author

	$doctypeList = array('doc', 'file', 'image', 'issue', 'link', 'review', 'vote');

	foreach ($doctypeList as $doctype) {
		$sql = "SELECT O.*, AF.community_oid
			FROM {$prefix}objects O LEFT JOIN {$prefix}class_{$doctype} AF ON (O.oid = AF.oid)
			WHERE O.type = 'f{$doctype}'";
		$result = $db->query($sql);
		while ($row = $db->getOne($result)) { // для каждого документа
			$community_oid = $row['community_oid']; unset($row['community_oid']);

			$data = unserialize($row['data']);
			if (array_key_exists('author_url', $data)) {
				$authors = array();
				//debug (__FUNCTION__ . " process {$row['oid']} : {$doctype}");
				$author_url = $data['author_url'];
				if (is_numeric($author_url)) {                     // это oid fpid_user
					$author = array();
					$author['oid'] = $author_url;
					$item_author = array(
						  'item_oid' => $row['oid'],
						'author_oid' => $author_url,
					);
					if (!$db->insert("{$prefix}item_author", $item_author)) {
						$patch->error = $db->error;
						return false;
					}
					$authors[] = $author;
				} elseif (is_string($author_url) && $author_url) { // это какой-то текст (возможно url, который каким-то
					                                                 // образом указывает на автора).
					$author = array(
						'community_oid' => $community_oid,
						'fullname' => $author_url,
					);
					$authors[] = $author;
				} else { // author_url содержит неведомую чушь
				//	debug (__FUNCTION__ . " unknown author_url: '".var_export($author_url, true)."'");
				}

				// обновим документ, удалим author_url, сохраним структуру authors
				unset($data['author_url']);
				if ($authors) $data['authors'] = $authors;

				$row['data'] = serialize($data);
				if (!$db->update("{$prefix}objects", $row, 'oid')) {
					$patch->error = $db->error;
					return false;
				}
			}
		}

		// удаляем author_url из таблицы class_{doctype}
		// HACK : 2008-06-16 : lucky
		// таблицы class_issue, class_vote не содержали author_url
		if (!in_array($doctype, array('issue', 'vote'))) {
			$sql = " ALTER TABLE `{$prefix}class_{$doctype}` DROP COLUMN `author_url` ";
			if (!$db->query($sql)) {
				$patch->error = $db->error;
				return false;
			}
		}
	}
	return true;
}

function update_db_review_fields ($patch)
{
	// обновить поля в review:
	// url -> subject_url
	// subject -> subject_title
	// description -> subject_description
	// isdn -> subject_isdn
	// authors -> subject_authors
	//
	// это затронуло class_review и class_allfeed. причем в allfeed:
	// ! url -> subject_url
	// ! description -> subject_description
	// subject -> subject_title
	// isdn -> subject_isdn
	// authors -> subject_authors
	// *(!) после апдейта не удалять из allfeed, а вписать NULL
	$db = $patch->db;
	$prefix = $db->db_prefix;

	// обновим структуру class_review
	$sql = "
		ALTER TABLE `{$prefix}class_review`
		   CHANGE COLUMN `url` `subject_url` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `description` `subject_description` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `subject` `subject_title` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `authors` `subject_authors` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `isdn` `subject_isdn` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
	";
	if (!$db->query($sql)) { // если нашли персону
		$patch->error = $db->error;
		return false;
	}

	// обновим структуру class_allfeed
	$sql = "
		ALTER TABLE `{$prefix}class_allfeed` DROP COLUMN `author_url`
		 , CHANGE COLUMN `subject` `subject_title` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `authors` `subject_authors` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , CHANGE COLUMN `isdn` `subject_isdn` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
		 , ADD COLUMN `subject_url` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `subject_authors`
		 , ADD COLUMN `subject_description` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `subject_url`
	";
	if (!$db->query($sql)) { // если нашли персону
		$patch->error = $db->error;
		return false;
	}

	// обновим данные в class_allfeed, которые не затронуло обновление структуры
	$sql = "
		UPDATE `{$prefix}class_allfeed`
			SET `subject_url` = `url`
			, `subject_description` = `description`
			, `url` = NULL
			, `description` = NULL
		WHERE `oid` IN (SELECT DISTINCT `oid` FROM {$prefix}objects O WHERE O.type = 'freview')
	";
	if (!$db->query($sql)) {
		$patch->error = $db->error;
		return false;
	}
	return true;

	// найдем всех review
	$sql = " SELECT * FROM {$prefix}objects O WHERE type = 'freview' ";
	$result = $db->query($sql);

	// обновим поля в объектах
	while ($row = $db->getOne($result)) {
		$data = unserialize($row['data']);

		if (array_key_exists(        'url', $data)) { $data[        'subject_url'] = $data[        'url']; unset($data['url']); }
		if (array_key_exists('description', $data)) { $data['subject_description'] = $data['description']; unset($data['description']); }
		if (array_key_exists(    'subject', $data)) { $data[      'subject_title'] = $data[    'subject']; unset($data['subject']); }
		if (array_key_exists(    'authors', $data)) { $data[    'subject_authors'] = $data[    'authors']; unset($data['authors']); }
		if (array_key_exists(       'isdn', $data)) { $data[       'subject_isdn'] = $data[       'isdn']; unset($data['isdn']); }

		$row['data'] = serialize($data);

		if (!$db->update("{$prefix}objects", $row, 'oid')) {
			$patch->error = $db->error;
			return false;
		}
	}
	return true;

} // end of function update_db_review_fields
